package com.zytlifeservice.filter;


import com.zytlifeservice.exception.UserException;
import com.zytlifeservice.util.AesUtils;
import com.zytlifeservice.util.SignUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by MJS on 2017/7/20.
 */

@Order(1)
@WebFilter(filterName = "urlFilter", urlPatterns = {"/waterCoal/wxPreCreate", "/waterCoal/preCreate", "/wiredTv/wxPreCreate"
        , "/wiredTv/preCreate", "/mobileRecharge/preCreateWxOrder", "/mobileRecharge/preCreate", "/flowRecharge/wxPayFlow", "/flowRecharge/payFlow"
        , "/broadBand/wxPreCreate", "/broadBand/preCreate", "/train/queryInfo", "/train/createWxOrder", "/train/createAlipayOrder"
        , "/airplane/createWxPayOrder", "/airplane/createAlipayOrder", "/user/registerUser", "/user/login", "/user/update/user"})
public class UrlFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(UrlFilter.class);

    private boolean isNeedVerify = true;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        if (!isNeedVerify) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        if (req.getMethod().equalsIgnoreCase("get")) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        } else if (req.getMethod().equalsIgnoreCase("post")) {
            String params = getRequestContent(req);
            logRequest(req);
            String header = req.getHeader("token-param");
            logger.info("my token-param：" + header);
            Map<String, String[]> parseData = null;
            try {
                String decryptContent = getDecryptContent(params);
                if (!verify(decryptContent)) {
                    logger.info("没通过验证");
                    throw new UserException("验证出错", 303);
                }
                logger.info("通过验证");
                parseData = parseParamsToMap(decryptContent);
            } catch (Exception e) {
                if (e instanceof UserException) {
                    throw (UserException) e;
                }
                e.printStackTrace();
            }
            servletRequest = new ParameterRequestWrapper(req, parseData);
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

    private boolean verify(String decryptContent) {
        Map<String, String> map = SignUtils.StringToMap(decryptContent);
        String sign = map.get("sign");
        try {
            String verifySign = SignUtils.generateSignature(map, "ea3a889332cbeea7e3a1498420c9f6b8");
            logger.info("参数的sign={}", sign);
            logger.info("服务器的sign={}", verifySign);
            if (verifySign.equals(sign)) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private String getDecryptContent(String params) throws Exception {
        logger.info("解密前内容={}", params);
        String decodeStr = AesUtils.decrypt("ea3a889332cbeea7e3a1498420c9f6b8", params);
        logger.info("解密后={}", decodeStr);
        return decodeStr;
    }

    private void logRequest(HttpServletRequest request) {
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String s = headerNames.nextElement();
            logger.info(s + "=" + request.getHeader(s));
        }
    }

    private String getRequestContent(HttpServletRequest request) throws IOException {
        String content = "";
        if ("POST".equalsIgnoreCase(request.getMethod())) {
            content = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
        }
        return content;
    }

    private Map<String, String[]> parseParamsToMap(String content) throws Exception {
        Map<String, String[]> map = new HashMap<>();
        String[] split = content.split("&");
        for (String s : split) {
            String[] rs = s.split("=");
            if (rs.length == 2) {
                map.put(rs[0], new String[]{rs[1]});
            } else {
                if (rs.length != 0) {
                    map.put(rs[0], new String[]{""});
                }
            }
        }
        return map;
    }

    @Override
    public void destroy() {

    }
}
